source: bootcd/isolinux/syslinux-6.03/gpxe/src/util/iccfix.c @ 26ffad7

Last change on this file since 26ffad7 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 3.2 KB
Line 
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 */
34static 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
81static 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
135int 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 */
Note: See TracBrowser for help on using the repository browser.