LibElf Implementation Notes
- The ELF(3) API allows applications to create, read and write plain ELF files (and to read
ar(1)archives, see below). The current designmmap's the content of the target file and makes the uninterpreted bits of the target available as ELF descriptor membere_rawfile.ELF_C_READoperations will map the underlying file read-only and usee_rawfiledirectly.ELF_C_WRITEoperations use freshlymalloc()'ed address ranges and will update thee_rawfilemember on anelf_update().ELF_C_RDWRoperations will map the file read-only, and will read information from there as needed when data from a given section is retrieved. The library will merge “clean” and “dirty” data and write out the new contents to the underlying file atelf_update()time. The “new” data will be then mapped in and the size of the mapped range would be adjusted as needed.
ar(1)archives have a few corners to be taken care of.- GNU
arcreates archives which have archive headers that start at even addresses. I.e., if a file being archived has an odd length, the data in the archive is padded with one 0x0D character. Extraction always uses the exact size of the file. Solarisar(1)appears to use 4 byte padding. It isn't clear how to tell the difference between a Solaris and GNUararchive. What this means is that when reading & parsing data from inside of anar(1)archive, we need to be prepared for misalignments. struct ar_hdrdescribed in/usr/include/ar.hhas limited space (16 bytes) for the name of the file. For archives containing files with longer names, an extended archive format is used, with special entries//,/?,/0…/9, denoting special members (an archive symbol table, an archive string table, etc.).
- API Issues:
elf_rand()is defined in the SVR4 ELF API as taking asize_tfor an offset into the archive. I.e., the prototype iself_rand(Elf *e, size_t offset). Using anoff_tseems to be more correct on 32 bit systems:elf_rand(Elf *e, off_t offset).- The SVR4 API uses
off_tfor thed_offmember of an Elf_Data structure andsize_tfor thed_sizemember. However, these types are architecture dependent;size_tis 32 bits on FreeBSD/i386 and 64 bits on FreeBSD/sparc64. I've defined these as of typeuint64_tso that 64 bit ELF objects can be handled on 32 bit systems without bugs caused by field width mismatches. gelf_newehdr()is defined in the SVR4 ELF API as returningunsigned long. However the return type should be aunionofElf32_Ehdr *andElf64_Ehdr *, or at leastvoid *. We can't portably assume that anunsigned longis large enough to hold a pointer value.gelf_newphdr()has a similar issue.- It isn't very clear what
elf_getident()needs to do if invoked on an ELF file opened for writing. I'm choosing to return ELF_E_SEQUENCE ifelf_getident()is invoked before a successfulelf_update().
- API Extensions
elf_setshstrndx(), for an application to set thee_shstrndxfield (or its equivalent if using extended section numbering).- As an extension to the
elf_flag*()APIs, a flag value of zero will query the current set of flags on an object without changing them. - GNU libelf has a set of extensions that allow removing sections and moving sections around in the file. Are these useful for our tools?
jb@has proposed that anelf_dump()API be added to -lelf.