Files
ipxe/src/util/iccfix.c
T
Michael Brown 8406115834 [build] Rename gPXE to iPXE
Access to the gpxe.org and etherboot.org domains and associated
resources has been revoked by the registrant of the domain.  Work
around this problem by renaming project from gPXE to iPXE, and
updating URLs to match.

Also update README, LOG and COPYRIGHTS to remove obsolete information.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
2010-04-19 23:43:39 +01:00

157 lines
3.2 KiB
C

#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <elf.h>
#include <ipxe/tables.h>
#define DEBUG 0
#define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
#define dprintf(...) do { \
if ( DEBUG ) \
fprintf ( stderr, __VA_ARGS__ ); \
} while ( 0 )
#ifdef SELF_INCLUDED
/**
* Fix up ICC alignments
*
* @v elf ELF header
* @ret rc Return status code
*
* See comments in tables.h for an explanation of why this monstrosity
* is necessary.
*/
static int ICCFIX ( void *elf ) {
ELF_EHDR *ehdr = elf;
ELF_SHDR *shdr = ( elf + ehdr->e_shoff );
size_t shentsize = ehdr->e_shentsize;
unsigned int shnum = ehdr->e_shnum;
ELF_SHDR *strtab = ( ( ( void * ) shdr ) +
( ehdr->e_shstrndx * shentsize ) );
char *strings = ( elf + strtab->sh_offset );
for ( ; shnum-- ; shdr = ( ( ( void * ) shdr ) + shentsize ) ) {
char *name = ( strings + shdr->sh_name );
unsigned long align = shdr->sh_addralign;
unsigned long new_align;
if ( ( strncmp ( name, ".tbl.", 5 ) == 0 ) &&
( align >= ICC_ALIGN_HACK_FACTOR ) ) {
new_align = ( align / ICC_ALIGN_HACK_FACTOR );
shdr->sh_addralign = new_align;
dprintf ( "Section \"%s\": alignment %d->%d\n",
name, align, new_align );
}
}
return 0;
}
#else /* SELF_INCLUDED */
#define SELF_INCLUDED
/* Include iccfix32() function */
#define ELF_EHDR Elf32_Ehdr
#define ELF_SHDR Elf32_Shdr
#define ICCFIX iccfix32
#include "iccfix.c"
#undef ELF_EHDR
#undef ELF_SHDR
#undef ICCFIX
/* Include iccfix64() function */
#define ELF_EHDR Elf64_Ehdr
#define ELF_SHDR Elf64_Shdr
#define ICCFIX iccfix64
#include "iccfix.c"
#undef ELF_EHDR
#undef ELF_SHDR
#undef ICCFIX
static int iccfix ( const char *filename ) {
int fd;
struct stat stat;
void *elf;
unsigned char *eident;
int rc;
/* Open and mmap file */
fd = open ( filename, O_RDWR );
if ( fd < 0 ) {
eprintf ( "Could not open %s: %s\n",
filename, strerror ( errno ) );
rc = -1;
goto err_open;
}
if ( fstat ( fd, &stat ) < 0 ) {
eprintf ( "Could not determine size of %s: %s\n",
filename, strerror ( errno ) );
rc = -1;
goto err_fstat;
}
elf = mmap ( NULL, stat.st_size, ( PROT_READ | PROT_WRITE ),
MAP_SHARED, fd, 0 );
if ( elf == MAP_FAILED ) {
eprintf ( "Could not map %s: %s\n",
filename, strerror ( errno ) );
rc = -1;
goto err_mmap;
}
/* Perform fixups */
eident = elf;
switch ( eident[EI_CLASS] ) {
case ELFCLASS32:
rc = iccfix32 ( elf );
break;
case ELFCLASS64:
rc = iccfix64 ( elf );
break;
default:
eprintf ( "Unknown ELF class %d in %s\n",
eident[EI_CLASS], filename );
rc = -1;
break;
}
munmap ( elf, stat.st_size );
err_mmap:
err_fstat:
close ( fd );
err_open:
return rc;
}
int main ( int argc, char **argv ) {
int i;
int rc;
/* Parse command line */
if ( argc < 2 ) {
eprintf ( "Syntax: %s <object_file>...\n", argv[0] );
exit ( 1 );
}
/* Process each object in turn */
for ( i = 1 ; i < argc ; i++ ) {
if ( ( rc = iccfix ( argv[i] ) ) != 0 ) {
eprintf ( "Could not fix up %s\n", argv[i] );
exit ( 1 );
}
}
return 0;
}
#endif /* SELF_INCLUDED */