ar(1)
archive creation using libelfWe would like applications to be able to create ar(1)
archive using libelf.
The new functions and symbols use an ELF_
/elf_
prefix to avoid polluting the namespace any more than is being done already by <libelf.h>
.
The proposed API changes are as follows:
Two new flags, namely ELF_F_ARCHIVE
and ELF_F_ARCHIVE_SYSV
will be defined in libelf.h
for use with elf_flagelf()
. These flag an Elf
descriptor as being for a new ar(1)
archive. These flags are only valid for use with Elf
descriptors that were created using ELF_C_WRITE
.
The default format for an archive would be the BSD format, using the ELF_F_ARCHIVE_SYSV
flag changes that to SYSV style.
Three new functions are defined:
elf_add_member
elf_add_symtab
elf_flagarhdr
elf_add_member
off_t elf_add_member(Elf *ar, ElfArhdr *arhdr, void *data);
This function adds object data to the current archive at the end. The header metadata for the object, in particular the size of data would be in arhdr. The return value is a "tentative" offset that may be used to construct an Elf_Arsym
table for the symbols in this object.
The offset is "tentative" because the actual sizes of the string and symbol table members, which must come before the data members themselves, aren't known at this point.
elf_add_symtab
int elf_add_symtab(Elf *ar, Elf_Arsym *ars, size_t nentries);
This API would add the symbol table ars to the archive. The as_off members for entries will be adjusted at the time the archive is written out to compensate for the size of the symbol table itself and for the archive string table.
elf_flagarhdr
unsigned int elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags);
Marks an Elf_Arhdr
structure as "dirty" for subsequent updation using elf_update()
.
In addition to the above, elf_update()
would be augmented to deal with ar(1)
archives.
With this API extension, the program flow to create an AR archive would be:
fd = open("/path/to/archive", O_WRONLY); ar = elf_begin(fd, ELF_C_WRITE, NULL); elf_flagelf(ar, ELF_C_SET, ELF_F_ARCHIVE); /* creating an archive */ while (...there are more members to add...) { e = ... get a pointer to raw data ...; arhdr = ... fill up the archive header ...; off = elf_add_member(ar, &arhdr, e); ... fill up members of the arsym array with this tentative offset value .. } elf_add_arsym(ar, arsym, nentries); /* add symbol table */ elf_update(ar, ELF_C_WRITE); /* and write it out */