• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdint.h>
2 #include <stddef.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <sys/mman.h>
11 #include <elf.h>
12 #include <gpxe/tables.h>
13 
14 #define DEBUG 0
15 
16 #define eprintf(...) fprintf ( stderr, __VA_ARGS__ )
17 
18 #define dprintf(...) do {						\
19 	if ( DEBUG )							\
20 		fprintf ( stderr, __VA_ARGS__ );			\
21 	} while ( 0 )
22 
23 #ifdef SELF_INCLUDED
24 
25 /**
26  * Fix up ICC alignments
27  *
28  * @v elf		ELF header
29  * @ret rc		Return status code
30  *
31  * See comments in tables.h for an explanation of why this monstrosity
32  * is necessary.
33  */
ICCFIX(void * elf)34 static int ICCFIX ( void *elf ) {
35 	ELF_EHDR *ehdr = elf;
36 	ELF_SHDR *shdr = ( elf + ehdr->e_shoff );
37 	size_t shentsize = ehdr->e_shentsize;
38 	unsigned int shnum = ehdr->e_shnum;
39 	ELF_SHDR *strtab = ( ( ( void * ) shdr ) +
40 			     ( ehdr->e_shstrndx * shentsize ) );
41 	char *strings = ( elf + strtab->sh_offset );
42 
43 	for ( ; shnum-- ; shdr = ( ( ( void * ) shdr ) + shentsize ) ) {
44 		char *name = ( strings + shdr->sh_name );
45 		unsigned long align = shdr->sh_addralign;
46 		unsigned long new_align;
47 
48 		if ( ( strncmp ( name, ".tbl.", 5 ) == 0 ) &&
49 		     ( align >= ICC_ALIGN_HACK_FACTOR ) ) {
50 			new_align = ( align / ICC_ALIGN_HACK_FACTOR );
51 			shdr->sh_addralign = new_align;
52 			dprintf ( "Section \"%s\": alignment %d->%d\n",
53 				  name, align, new_align );
54 		}
55 	}
56 	return 0;
57 }
58 
59 #else /* SELF_INCLUDED */
60 
61 #define SELF_INCLUDED
62 
63 /* Include iccfix32() function */
64 #define ELF_EHDR Elf32_Ehdr
65 #define ELF_SHDR Elf32_Shdr
66 #define ICCFIX iccfix32
67 #include "iccfix.c"
68 #undef ELF_EHDR
69 #undef ELF_SHDR
70 #undef ICCFIX
71 
72 /* Include iccfix64() function */
73 #define ELF_EHDR Elf64_Ehdr
74 #define ELF_SHDR Elf64_Shdr
75 #define ICCFIX iccfix64
76 #include "iccfix.c"
77 #undef ELF_EHDR
78 #undef ELF_SHDR
79 #undef ICCFIX
80 
iccfix(const char * filename)81 static int iccfix ( const char *filename ) {
82 	int fd;
83 	struct stat stat;
84 	void *elf;
85 	unsigned char *eident;
86 	int rc;
87 
88 	/* Open and mmap file */
89 	fd = open ( filename, O_RDWR );
90 	if ( fd < 0 ) {
91 		eprintf ( "Could not open %s: %s\n",
92 			  filename, strerror ( errno ) );
93 		rc = -1;
94 		goto err_open;
95 	}
96 	if ( fstat ( fd, &stat ) < 0 ) {
97 		eprintf ( "Could not determine size of %s: %s\n",
98 			  filename, strerror ( errno ) );
99 		rc = -1;
100 		goto err_fstat;
101 	}
102 	elf = mmap ( NULL, stat.st_size, ( PROT_READ | PROT_WRITE ),
103 		     MAP_SHARED, fd, 0 );
104 	if ( elf == MAP_FAILED ) {
105 		eprintf ( "Could not map %s: %s\n",
106 			  filename, strerror ( errno ) );
107 		rc = -1;
108 		goto err_mmap;
109 	}
110 
111 	/* Perform fixups */
112 	eident = elf;
113 	switch ( eident[EI_CLASS] ) {
114 	case ELFCLASS32:
115 		rc = iccfix32 ( elf );
116 		break;
117 	case ELFCLASS64:
118 		rc = iccfix64 ( elf );
119 		break;
120 	default:
121 		eprintf ( "Unknown ELF class %d in %s\n",
122 			  eident[EI_CLASS], filename );
123 		rc = -1;
124 		break;
125 	}
126 
127 	munmap ( elf, stat.st_size );
128  err_mmap:
129  err_fstat:
130 	close ( fd );
131  err_open:
132 	return rc;
133 }
134 
main(int argc,char ** argv)135 int main ( int argc, char **argv ) {
136 	int i;
137 	int rc;
138 
139 	/* Parse command line */
140 	if ( argc < 2 ) {
141 		eprintf ( "Syntax: %s <object_file>...\n", argv[0] );
142 		exit ( 1 );
143 	}
144 
145 	/* Process each object in turn */
146 	for ( i = 1 ; i < argc ; i++ ) {
147 		if ( ( rc = iccfix ( argv[i] ) ) != 0 ) {
148 			eprintf ( "Could not fix up %s\n", argv[i] );
149 			exit ( 1 );
150 		}
151 	}
152 
153 	return 0;
154 }
155 
156 #endif /* SELF_INCLUDED */
157