kldxref: improve style(9)

Address style issues including some previously raised in D13923.

- Use designated initializers for structs
- Always use bracketed return style
- No initialization in declarations
- Align function prototype names
- Remove old commented code/unused includes

Submitted by:	Mitchell Horne <mhorne063@gmail.com>
Reviewed by:	kib
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D13943
This commit is contained in:
emaste 2018-01-17 19:59:43 +00:00
parent 036ebddf97
commit 7a589d5c51
5 changed files with 233 additions and 231 deletions

View File

@ -36,84 +36,89 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/linker.h> #include <sys/linker.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <machine/elf.h>
#define FREEBSD_ELF
#include <err.h> #include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <machine/elf.h>
#define FREEBSD_ELF
#include "ef.h" #include "ef.h"
#define MAXSEGS 3 #define MAXSEGS 3
struct ef_file { struct ef_file {
char* ef_name; char *ef_name;
struct elf_file *ef_efile; struct elf_file *ef_efile;
Elf_Phdr * ef_ph; Elf_Phdr *ef_ph;
int ef_fd; int ef_fd;
int ef_type; int ef_type;
Elf_Ehdr ef_hdr; Elf_Ehdr ef_hdr;
void* ef_fpage; /* First block of the file */ void *ef_fpage; /* First block of the file */
int ef_fplen; /* length of first block */ int ef_fplen; /* length of first block */
Elf_Dyn* ef_dyn; /* Symbol table etc. */ Elf_Dyn *ef_dyn; /* Symbol table etc. */
Elf_Hashelt ef_nbuckets; Elf_Hashelt ef_nbuckets;
Elf_Hashelt ef_nchains; Elf_Hashelt ef_nchains;
Elf_Hashelt* ef_buckets; Elf_Hashelt *ef_buckets;
Elf_Hashelt* ef_chains; Elf_Hashelt *ef_chains;
Elf_Hashelt* ef_hashtab; Elf_Hashelt *ef_hashtab;
Elf_Off ef_stroff; Elf_Off ef_stroff;
caddr_t ef_strtab; caddr_t ef_strtab;
int ef_strsz; int ef_strsz;
Elf_Off ef_symoff; Elf_Off ef_symoff;
Elf_Sym* ef_symtab; Elf_Sym *ef_symtab;
int ef_nsegs; int ef_nsegs;
Elf_Phdr * ef_segs[MAXSEGS]; Elf_Phdr *ef_segs[MAXSEGS];
int ef_verbose; int ef_verbose;
Elf_Rel * ef_rel; /* relocation table */ Elf_Rel *ef_rel; /* relocation table */
int ef_relsz; /* number of entries */ int ef_relsz; /* number of entries */
Elf_Rela * ef_rela; /* relocation table */ Elf_Rela *ef_rela; /* relocation table */
int ef_relasz; /* number of entries */ int ef_relasz; /* number of entries */
}; };
static void ef_print_phdr(Elf_Phdr *); static void ef_print_phdr(Elf_Phdr *);
static u_long ef_get_offset(elf_file_t, Elf_Off); static u_long ef_get_offset(elf_file_t, Elf_Off);
static int ef_parse_dynamic(elf_file_t); static int ef_parse_dynamic(elf_file_t);
static int ef_get_type(elf_file_t ef); static int ef_get_type(elf_file_t ef);
static int ef_close(elf_file_t ef); static int ef_close(elf_file_t ef);
static int ef_read(elf_file_t ef, Elf_Off offset, size_t len, void* dest); static int ef_read(elf_file_t ef, Elf_Off offset, size_t len, void* dest);
static int ef_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void **ptr); static int ef_read_entry(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_seg_read(elf_file_t ef, Elf_Off offset, size_t len, void *dest); void **ptr);
static int ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len,
void *dest); static int ef_seg_read(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, void *dest);
char *dest); static int ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void *dest);
void **ptr); static int ef_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len, char *dest);
void **ptr); static int ef_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len,
static Elf_Addr ef_symaddr(elf_file_t ef, Elf_Size symidx); void **ptr);
static int ef_lookup_set(elf_file_t ef, const char *name, long *startp, static int ef_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len,
long *stopp, long *countp); void **ptr);
static int ef_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym);
static Elf_Addr ef_symaddr(elf_file_t ef, Elf_Size symidx);
static int ef_lookup_set(elf_file_t ef, const char *name, long *startp,
long *stopp, long *countp);
static int ef_lookup_symbol(elf_file_t ef, const char* name,
Elf_Sym** sym);
static struct elf_file_ops ef_file_ops = { static struct elf_file_ops ef_file_ops = {
ef_get_type, .get_type = ef_get_type,
ef_close, .close = ef_close,
ef_read, .read = ef_read,
ef_read_entry, .read_entry = ef_read_entry,
ef_seg_read, .seg_read = ef_seg_read,
ef_seg_read_rel, .seg_read_rel = ef_seg_read_rel,
ef_seg_read_string, .seg_read_string = ef_seg_read_string,
ef_seg_read_entry, .seg_read_entry = ef_seg_read_entry,
ef_seg_read_entry_rel, .seg_read_entry_rel = ef_seg_read_entry_rel,
ef_symaddr, .symaddr = ef_symaddr,
ef_lookup_set, .lookup_set = ef_lookup_set,
ef_lookup_symbol .lookup_symbol = ef_lookup_symbol
}; };
static void static void
@ -139,10 +144,10 @@ ef_get_offset(elf_file_t ef, Elf_Off off)
for (i = 0; i < ef->ef_nsegs; i++) { for (i = 0; i < ef->ef_nsegs; i++) {
ph = ef->ef_segs[i]; ph = ef->ef_segs[i];
if (off >= ph->p_vaddr && off < ph->p_vaddr + ph->p_memsz) { if (off >= ph->p_vaddr && off < ph->p_vaddr + ph->p_memsz) {
return ph->p_offset + (off - ph->p_vaddr); return (ph->p_offset + (off - ph->p_vaddr));
} }
} }
return 0; return (0);
} }
static int static int
@ -158,26 +163,26 @@ ef_get_type(elf_file_t ef)
static unsigned long static unsigned long
elf_hash(const char *name) elf_hash(const char *name)
{ {
const unsigned char *p = (const unsigned char *) name; unsigned long h, g;
unsigned long h = 0; const unsigned char *p;
unsigned long g;
h = 0;
p = (const unsigned char *)name;
while (*p != '\0') { while (*p != '\0') {
h = (h << 4) + *p++; h = (h << 4) + *p++;
if ((g = h & 0xf0000000) != 0) if ((g = h & 0xf0000000) != 0)
h ^= g >> 24; h ^= g >> 24;
h &= ~g; h &= ~g;
} }
return h; return (h);
} }
static int static int
ef_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym) ef_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym)
{ {
unsigned long symnum; unsigned long hash, symnum;
Elf_Sym* symp; Elf_Sym *symp;
char *strp; char *strp;
unsigned long hash;
/* First, search hashed global symbols */ /* First, search hashed global symbols */
hash = elf_hash(name); hash = elf_hash(name);
@ -187,14 +192,14 @@ ef_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym)
if (symnum >= ef->ef_nchains) { if (symnum >= ef->ef_nchains) {
warnx("ef_lookup_symbol: file %s have corrupted symbol table\n", warnx("ef_lookup_symbol: file %s have corrupted symbol table\n",
ef->ef_name); ef->ef_name);
return ENOENT; return (ENOENT);
} }
symp = ef->ef_symtab + symnum; symp = ef->ef_symtab + symnum;
if (symp->st_name == 0) { if (symp->st_name == 0) {
warnx("ef_lookup_symbol: file %s have corrupted symbol table\n", warnx("ef_lookup_symbol: file %s have corrupted symbol table\n",
ef->ef_name); ef->ef_name);
return ENOENT; return (ENOENT);
} }
strp = ef->ef_strtab + symp->st_name; strp = ef->ef_strtab + symp->st_name;
@ -204,15 +209,15 @@ ef_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym)
(symp->st_value != 0 && (symp->st_value != 0 &&
ELF_ST_TYPE(symp->st_info) == STT_FUNC)) { ELF_ST_TYPE(symp->st_info) == STT_FUNC)) {
*sym = symp; *sym = symp;
return 0; return (0);
} else } else
return ENOENT; return (ENOENT);
} }
symnum = ef->ef_chains[symnum]; symnum = ef->ef_chains[symnum];
} }
return ENOENT; return (ENOENT);
} }
static int static int
@ -226,19 +231,19 @@ ef_lookup_set(elf_file_t ef, const char *name, long *startp, long *stopp,
len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */ len = strlen(name) + sizeof("__start_set_"); /* sizeof includes \0 */
setsym = malloc(len); setsym = malloc(len);
if (setsym == NULL) if (setsym == NULL)
return (ENOMEM); return (errno);
/* get address of first entry */ /* get address of first entry */
snprintf(setsym, len, "%s%s", "__start_set_", name); snprintf(setsym, len, "%s%s", "__start_set_", name);
error = ef_lookup_symbol(ef, setsym, &sym); error = ef_lookup_symbol(ef, setsym, &sym);
if (error) if (error != 0)
goto out; goto out;
*startp = sym->st_value; *startp = sym->st_value;
/* get address of last entry */ /* get address of last entry */
snprintf(setsym, len, "%s%s", "__stop_set_", name); snprintf(setsym, len, "%s%s", "__stop_set_", name);
error = ef_lookup_symbol(ef, setsym, &sym); error = ef_lookup_symbol(ef, setsym, &sym);
if (error) if (error != 0)
goto out; goto out;
*stopp = sym->st_value; *stopp = sym->st_value;
@ -270,7 +275,6 @@ ef_parse_dynamic(elf_file_t ef)
{ {
Elf_Dyn *dp; Elf_Dyn *dp;
Elf_Hashelt hashhdr[2]; Elf_Hashelt hashhdr[2];
/* int plttype = DT_REL;*/
int error; int error;
Elf_Off rel_off; Elf_Off rel_off;
Elf_Off rela_off; Elf_Off rela_off;
@ -287,19 +291,19 @@ ef_parse_dynamic(elf_file_t ef)
case DT_HASH: case DT_HASH:
error = ef_read(ef, ef_get_offset(ef, dp->d_un.d_ptr), error = ef_read(ef, ef_get_offset(ef, dp->d_un.d_ptr),
sizeof(hashhdr), hashhdr); sizeof(hashhdr), hashhdr);
if (error) { if (error != 0) {
warnx("can't read hash header (%lx)", warnx("can't read hash header (%lx)",
ef_get_offset(ef, dp->d_un.d_ptr)); ef_get_offset(ef, dp->d_un.d_ptr));
return error; return (error);
} }
ef->ef_nbuckets = hashhdr[0]; ef->ef_nbuckets = hashhdr[0];
ef->ef_nchains = hashhdr[1]; ef->ef_nchains = hashhdr[1];
error = ef_read_entry(ef, -1, error = ef_read_entry(ef, -1,
(hashhdr[0] + hashhdr[1]) * sizeof(Elf_Hashelt), (hashhdr[0] + hashhdr[1]) * sizeof(Elf_Hashelt),
(void**)&ef->ef_hashtab); (void**)&ef->ef_hashtab);
if (error) { if (error != 0) {
warnx("can't read hash table"); warnx("can't read hash table");
return error; return (error);
} }
ef->ef_buckets = ef->ef_hashtab; ef->ef_buckets = ef->ef_hashtab;
ef->ef_chains = ef->ef_buckets + ef->ef_nbuckets; ef->ef_chains = ef->ef_buckets + ef->ef_nbuckets;
@ -315,7 +319,7 @@ ef_parse_dynamic(elf_file_t ef)
break; break;
case DT_SYMENT: case DT_SYMENT:
if (dp->d_un.d_val != sizeof(Elf_Sym)) if (dp->d_un.d_val != sizeof(Elf_Sym))
return EFTYPE; return (EFTYPE);
break; break;
case DT_REL: case DT_REL:
if (rel_off != 0) if (rel_off != 0)
@ -351,11 +355,11 @@ ef_parse_dynamic(elf_file_t ef)
} }
if (ef->ef_symoff == 0) { if (ef->ef_symoff == 0) {
warnx("%s: no .dynsym section found\n", ef->ef_name); warnx("%s: no .dynsym section found\n", ef->ef_name);
return EFTYPE; return (EFTYPE);
} }
if (ef->ef_stroff == 0) { if (ef->ef_stroff == 0) {
warnx("%s: no .dynstr section found\n", ef->ef_name); warnx("%s: no .dynstr section found\n", ef->ef_name);
return EFTYPE; return (EFTYPE);
} }
if (ef_read_entry(ef, ef_get_offset(ef, ef->ef_symoff), if (ef_read_entry(ef, ef_get_offset(ef, ef->ef_symoff),
ef->ef_nchains * sizeof(Elf_Sym), ef->ef_nchains * sizeof(Elf_Sym),
@ -363,12 +367,12 @@ ef_parse_dynamic(elf_file_t ef)
if (ef->ef_verbose) if (ef->ef_verbose)
warnx("%s: can't load .dynsym section (0x%lx)", warnx("%s: can't load .dynsym section (0x%lx)",
ef->ef_name, (long)ef->ef_symoff); ef->ef_name, (long)ef->ef_symoff);
return EIO; return (EIO);
} }
if (ef_read_entry(ef, ef_get_offset(ef, ef->ef_stroff), ef->ef_strsz, if (ef_read_entry(ef, ef_get_offset(ef, ef->ef_stroff), ef->ef_strsz,
(void**)&ef->ef_strtab) != 0) { (void**)&ef->ef_strtab) != 0) {
warnx("can't load .dynstr section"); warnx("can't load .dynstr section");
return EIO; return (EIO);
} }
if (rel_off != 0) { if (rel_off != 0) {
if (rel_entry == 0) { if (rel_entry == 0) {
@ -420,7 +424,7 @@ ef_parse_dynamic(elf_file_t ef)
warnx("%s: %d RELA entries", ef->ef_name, warnx("%s: %d RELA entries", ef->ef_name,
ef->ef_relasz); ef->ef_relasz);
} }
return 0; return (0);
} }
static int static int
@ -430,14 +434,14 @@ ef_read(elf_file_t ef, Elf_Off offset, size_t len, void*dest)
if (offset != (Elf_Off)-1) { if (offset != (Elf_Off)-1) {
if (lseek(ef->ef_fd, offset, SEEK_SET) == -1) if (lseek(ef->ef_fd, offset, SEEK_SET) == -1)
return EIO; return (EIO);
} }
r = read(ef->ef_fd, dest, len); r = read(ef->ef_fd, dest, len);
if (r != -1 && (size_t)r == len) if (r != -1 && (size_t)r == len)
return 0; return (0);
else else
return EIO; return (EIO);
} }
static int static int
@ -447,23 +451,24 @@ ef_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void**ptr)
*ptr = malloc(len); *ptr = malloc(len);
if (*ptr == NULL) if (*ptr == NULL)
return ENOMEM; return (errno);
error = ef_read(ef, offset, len, *ptr); error = ef_read(ef, offset, len, *ptr);
if (error) if (error != 0)
free(*ptr); free(*ptr);
return error; return (error);
} }
static int static int
ef_seg_read(elf_file_t ef, Elf_Off offset, size_t len, void*dest) ef_seg_read(elf_file_t ef, Elf_Off offset, size_t len, void*dest)
{ {
u_long ofs = ef_get_offset(ef, offset); u_long ofs;
ofs = ef_get_offset(ef, offset);
if (ofs == 0) { if (ofs == 0) {
if (ef->ef_verbose) if (ef->ef_verbose)
warnx("ef_seg_read(%s): zero offset (%lx:%ld)", warnx("ef_seg_read(%s): zero offset (%lx:%ld)",
ef->ef_name, (long)offset, ofs); ef->ef_name, (long)offset, ofs);
return EFAULT; return (EFAULT);
} }
return ef_read(ef, ofs, len, dest); return ef_read(ef, ofs, len, dest);
} }
@ -471,16 +476,17 @@ ef_seg_read(elf_file_t ef, Elf_Off offset, size_t len, void*dest)
static int static int
ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len, void*dest) ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len, void*dest)
{ {
u_long ofs = ef_get_offset(ef, offset); u_long ofs;
const Elf_Rela *a; const Elf_Rela *a;
const Elf_Rel *r; const Elf_Rel *r;
int error; int error;
ofs = ef_get_offset(ef, offset);
if (ofs == 0) { if (ofs == 0) {
if (ef->ef_verbose) if (ef->ef_verbose)
warnx("ef_seg_read_rel(%s): zero offset (%lx:%ld)", warnx("ef_seg_read_rel(%s): zero offset (%lx:%ld)",
ef->ef_name, (long)offset, ofs); ef->ef_name, (long)offset, ofs);
return EFAULT; return (EFAULT);
} }
if ((error = ef_read(ef, ofs, len, dest)) != 0) if ((error = ef_read(ef, ofs, len, dest)) != 0)
return (error); return (error);
@ -503,9 +509,10 @@ ef_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len, void*dest)
static int static int
ef_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, char *dest) ef_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, char *dest)
{ {
u_long ofs = ef_get_offset(ef, offset); u_long ofs;
ssize_t r; ssize_t r;
ofs = ef_get_offset(ef, offset);
if (ofs == 0 || ofs == (Elf_Off)-1) { if (ofs == 0 || ofs == (Elf_Off)-1) {
if (ef->ef_verbose) if (ef->ef_verbose)
warnx("ef_seg_read_string(%s): bad offset (%lx:%ld)", warnx("ef_seg_read_string(%s): bad offset (%lx:%ld)",
@ -529,11 +536,11 @@ ef_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void**ptr)
*ptr = malloc(len); *ptr = malloc(len);
if (*ptr == NULL) if (*ptr == NULL)
return ENOMEM; return (errno);
error = ef_seg_read(ef, offset, len, *ptr); error = ef_seg_read(ef, offset, len, *ptr);
if (error) if (error != 0)
free(*ptr); free(*ptr);
return error; return (error);
} }
static int static int
@ -543,11 +550,11 @@ ef_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len, void**ptr)
*ptr = malloc(len); *ptr = malloc(len);
if (*ptr == NULL) if (*ptr == NULL)
return ENOMEM; return (errno);
error = ef_seg_read_rel(ef, offset, len, *ptr); error = ef_seg_read_rel(ef, offset, len, *ptr);
if (error) if (error != 0)
free(*ptr); free(*ptr);
return error; return (error);
} }
int int
@ -562,14 +569,14 @@ ef_open(const char *filename, struct elf_file *efile, int verbose)
Elf_Phdr *phdr, *phdyn, *phlimit; Elf_Phdr *phdr, *phdyn, *phlimit;
if (filename == NULL) if (filename == NULL)
return EFTYPE; return (EINVAL);
if ((fd = open(filename, O_RDONLY)) == -1) if ((fd = open(filename, O_RDONLY)) == -1)
return errno; return (errno);
ef = malloc(sizeof(*ef)); ef = malloc(sizeof(*ef));
if (ef == NULL) { if (ef == NULL) {
close(fd); close(fd);
return (ENOMEM); return (errno);
} }
efile->ef_ef = ef; efile->ef_ef = ef;
@ -637,38 +644,31 @@ ef_open(const char *filename, struct elf_file *efile, int verbose)
break; break;
} }
error = ef_parse_dynamic(ef); error = ef_parse_dynamic(ef);
if (error) if (error != 0)
break; break;
if (hdr->e_type == ET_DYN) { if (hdr->e_type == ET_DYN) {
ef->ef_type = EFT_KLD; ef->ef_type = EFT_KLD;
/* pad = (u_int)dest & PAGE_MASK;
if (pad)
dest += PAGE_SIZE - pad;*/
error = 0; error = 0;
} else if (hdr->e_type == ET_EXEC) { } else if (hdr->e_type == ET_EXEC) {
/* dest = hdr->e_entry;
if (dest == 0)
break;*/
ef->ef_type = EFT_KERNEL; ef->ef_type = EFT_KERNEL;
error = 0; error = 0;
} else } else
break; break;
} while(0); } while(0);
if (error) if (error != 0)
ef_close(ef); ef_close(ef);
return error; return (error);
} }
static int static int
ef_close(elf_file_t ef) ef_close(elf_file_t ef)
{ {
close(ef->ef_fd); close(ef->ef_fd);
/* if (ef->ef_fpage)
free(ef->ef_fpage);*/
if (ef->ef_name) if (ef->ef_name)
free(ef->ef_name); free(ef->ef_name);
ef->ef_efile->ef_ops = NULL; ef->ef_efile->ef_ops = NULL;
ef->ef_efile->ef_ef = NULL; ef->ef_efile->ef_ef = NULL;
free(ef); free(ef);
return 0; return (0);
} }

View File

@ -36,8 +36,6 @@
#include "ef.h" #include "ef.h"
#include <stdio.h>
/* /*
* Apply relocations to the values obtained from the file. `relbase' is the * Apply relocations to the values obtained from the file. `relbase' is the
* target relocation address of the section, and `dataoff/len' is the region * target relocation address of the section, and `dataoff/len' is the region
@ -47,9 +45,9 @@ int
ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase, ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase,
Elf_Off dataoff, size_t len, void *dest) Elf_Off dataoff, size_t len, void *dest)
{ {
Elf_Addr *where, addend; Elf_Addr *where, addend;
Elf_Size rtype, symidx; Elf_Size rtype;
const Elf_Rela *rela; const Elf_Rela *rela;
if (reltype != EF_RELOC_RELA) if (reltype != EF_RELOC_RELA)
return (EINVAL); return (EINVAL);
@ -58,10 +56,9 @@ ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase,
where = (Elf_Addr *) ((Elf_Off)dest - dataoff + rela->r_offset); where = (Elf_Addr *) ((Elf_Off)dest - dataoff + rela->r_offset);
addend = rela->r_addend; addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info); rtype = ELF_R_TYPE(rela->r_info);
symidx = ELF_R_SYM(rela->r_info);
if ((char *)where < (char *)dest || (char *)where >= (char *)dest + len) if ((char *)where < (char *)dest || (char *)where >= (char *)dest + len)
return (0); return (0);
switch(rtype) { switch(rtype) {
case R_AARCH64_RELATIVE: case R_AARCH64_RELATIVE:

View File

@ -38,16 +38,16 @@
#include <sys/param.h> #include <sys/param.h>
#include <sys/linker.h> #include <sys/linker.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <machine/elf.h>
#define FREEBSD_ELF
#include <err.h> #include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <machine/elf.h>
#define FREEBSD_ELF
#include "ef.h" #include "ef.h"
@ -101,39 +101,41 @@ struct ef_file {
int ef_verbose; int ef_verbose;
}; };
static int ef_obj_get_type(elf_file_t ef); static int ef_obj_get_type(elf_file_t ef);
static int ef_obj_close(elf_file_t ef); static int ef_obj_close(elf_file_t ef);
static int ef_obj_read(elf_file_t ef, Elf_Off offset, size_t len, void* dest); static int ef_obj_read(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_obj_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void* dest);
void **ptr); static int ef_obj_read_entry(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_obj_seg_read(elf_file_t ef, Elf_Off offset, size_t len, void **ptr);
void *dest); static int ef_obj_seg_read(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_obj_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len, void *dest);
void *dest); static int ef_obj_seg_read_rel(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_obj_seg_read_string(elf_file_t ef, Elf_Off offset, size_t len, void *dest);
char *dest); static int ef_obj_seg_read_string(elf_file_t ef, Elf_Off offset,
static int ef_obj_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, size_t len, char *dest);
void **ptr); static int ef_obj_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len,
static int ef_obj_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len, void **ptr);
void **ptr); static int ef_obj_seg_read_entry_rel(elf_file_t ef, Elf_Off offset,
static Elf_Addr ef_obj_symaddr(elf_file_t ef, Elf_Size symidx); size_t len, void **ptr);
static int ef_obj_lookup_set(elf_file_t ef, const char *name, long *startp, static Elf_Addr ef_obj_symaddr(elf_file_t ef, Elf_Size symidx);
long *stopp, long *countp); static int ef_obj_lookup_set(elf_file_t ef, const char *name, long *startp,
static int ef_obj_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym); long *stopp, long *countp);
static int ef_obj_lookup_symbol(elf_file_t ef, const char* name,
Elf_Sym** sym);
static struct elf_file_ops ef_obj_file_ops = { static struct elf_file_ops ef_obj_file_ops = {
ef_obj_get_type, .get_type = ef_obj_get_type,
ef_obj_close, .close = ef_obj_close,
ef_obj_read, .read = ef_obj_read,
ef_obj_read_entry, .read_entry = ef_obj_read_entry,
ef_obj_seg_read, .seg_read = ef_obj_seg_read,
ef_obj_seg_read_rel, .seg_read_rel = ef_obj_seg_read_rel,
ef_obj_seg_read_string, .seg_read_string = ef_obj_seg_read_string,
ef_obj_seg_read_entry, .seg_read_entry = ef_obj_seg_read_entry,
ef_obj_seg_read_entry_rel, .seg_read_entry_rel = ef_obj_seg_read_entry_rel,
ef_obj_symaddr, .symaddr = ef_obj_symaddr,
ef_obj_lookup_set, .lookup_set = ef_obj_lookup_set,
ef_obj_lookup_symbol .lookup_symbol = ef_obj_lookup_symbol
}; };
static int static int
@ -154,10 +156,10 @@ ef_obj_lookup_symbol(elf_file_t ef, const char* name, Elf_Sym** sym)
strp = ef->ddbstrtab + symp->st_name; strp = ef->ddbstrtab + symp->st_name;
if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) { if (symp->st_shndx != SHN_UNDEF && strcmp(name, strp) == 0) {
*sym = symp; *sym = symp;
return 0; return (0);
} }
} }
return ENOENT; return (ENOENT);
} }
static int static int
@ -200,14 +202,14 @@ ef_obj_read(elf_file_t ef, Elf_Off offset, size_t len, void *dest)
if (offset != (Elf_Off)-1) { if (offset != (Elf_Off)-1) {
if (lseek(ef->ef_fd, offset, SEEK_SET) == -1) if (lseek(ef->ef_fd, offset, SEEK_SET) == -1)
return EIO; return (EIO);
} }
r = read(ef->ef_fd, dest, len); r = read(ef->ef_fd, dest, len);
if (r != -1 && (size_t)r == len) if (r != -1 && (size_t)r == len)
return 0; return (0);
else else
return EIO; return (EIO);
} }
static int static int
@ -217,11 +219,11 @@ ef_obj_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void **ptr)
*ptr = malloc(len); *ptr = malloc(len);
if (*ptr == NULL) if (*ptr == NULL)
return ENOMEM; return (errno);
error = ef_obj_read(ef, offset, len, *ptr); error = ef_obj_read(ef, offset, len, *ptr);
if (error) if (error != 0)
free(*ptr); free(*ptr);
return error; return (error);
} }
static int static int
@ -329,11 +331,11 @@ ef_obj_seg_read_entry(elf_file_t ef, Elf_Off offset, size_t len, void **ptr)
*ptr = malloc(len); *ptr = malloc(len);
if (*ptr == NULL) if (*ptr == NULL)
return ENOMEM; return (errno);
error = ef_obj_seg_read(ef, offset, len, *ptr); error = ef_obj_seg_read(ef, offset, len, *ptr);
if (error) if (error != 0)
free(*ptr); free(*ptr);
return error; return (error);
} }
static int static int
@ -344,11 +346,11 @@ ef_obj_seg_read_entry_rel(elf_file_t ef, Elf_Off offset, size_t len,
*ptr = malloc(len); *ptr = malloc(len);
if (*ptr == NULL) if (*ptr == NULL)
return ENOMEM; return (errno);
error = ef_obj_seg_read_rel(ef, offset, len, *ptr); error = ef_obj_seg_read_rel(ef, offset, len, *ptr);
if (error) if (error != 0)
free(*ptr); free(*ptr);
return error; return (error);
} }
int int
@ -365,14 +367,14 @@ ef_obj_open(const char *filename, struct elf_file *efile, int verbose)
int i, j, nbytes, nsym, shstrindex, symstrindex, symtabindex; int i, j, nbytes, nsym, shstrindex, symstrindex, symtabindex;
if (filename == NULL) if (filename == NULL)
return EFTYPE; return (EINVAL);
if ((fd = open(filename, O_RDONLY)) == -1) if ((fd = open(filename, O_RDONLY)) == -1)
return errno; return (errno);
ef = calloc(1, sizeof(*ef)); ef = calloc(1, sizeof(*ef));
if (ef == NULL) { if (ef == NULL) {
close(fd); close(fd);
return (ENOMEM); return (errno);
} }
efile->ef_ef = ef; efile->ef_ef = ef;
@ -587,9 +589,9 @@ ef_obj_open(const char *filename, struct elf_file *efile, int verbose)
} }
error = 0; error = 0;
out: out:
if (error) if (error != 0)
ef_obj_close(ef); ef_obj_close(ef);
return error; return (error);
} }
static int static int
@ -628,5 +630,5 @@ ef_obj_close(elf_file_t ef)
ef->ef_efile->ef_ef = NULL; ef->ef_efile->ef_ef = NULL;
free(ef); free(ef);
return 0; return (0);
} }

View File

@ -38,8 +38,6 @@
#include "ef.h" #include "ef.h"
#include <stdio.h>
/* /*
* Apply relocations to the values obtained from the file. `relbase' is the * Apply relocations to the values obtained from the file. `relbase' is the
* target relocation address of the section, and `dataoff/len' is the region * target relocation address of the section, and `dataoff/len' is the region
@ -49,9 +47,9 @@ int
ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase, ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase,
Elf_Off dataoff, size_t len, void *dest) Elf_Off dataoff, size_t len, void *dest)
{ {
Elf_Addr *where, addend; Elf_Addr *where, addend;
Elf_Size rtype, symidx; Elf_Size rtype;
const Elf_Rela *rela; const Elf_Rela *rela;
if (reltype != EF_RELOC_RELA) if (reltype != EF_RELOC_RELA)
return (EINVAL); return (EINVAL);
@ -60,17 +58,16 @@ ef_reloc(struct elf_file *ef, const void *reldata, int reltype, Elf_Off relbase,
where = (Elf_Addr *) ((Elf_Off)dest - dataoff + rela->r_offset); where = (Elf_Addr *) ((Elf_Off)dest - dataoff + rela->r_offset);
addend = rela->r_addend; addend = rela->r_addend;
rtype = ELF_R_TYPE(rela->r_info); rtype = ELF_R_TYPE(rela->r_info);
symidx = ELF_R_SYM(rela->r_info);
if ((char *)where < (char *)dest || (char *)where >= (char *)dest + len) if ((char *)where < (char *)dest || (char *)where >= (char *)dest + len)
return (0); return (0);
switch(rtype) { switch(rtype) {
case R_PPC_RELATIVE: /* word32 B + A */ case R_PPC_RELATIVE: /* word32 B + A */
*where = relbase + addend; *where = relbase + addend;
break; break;
default: default:
warnx("unhandled relocation type %d", rtype); warnx("unhandled relocation type %lu", rtype);
} }
return (0); return (0);
} }

View File

@ -45,21 +45,23 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/module.h> #include <sys/module.h>
#define FREEBSD_ELF #define FREEBSD_ELF
#include <err.h> #include <err.h>
#include <errno.h>
#include <fts.h> #include <fts.h>
#include <string.h> #include <stdbool.h>
#include <machine/elf.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <machine/elf.h>
#include "ef.h" #include "ef.h"
#define MAXRECSIZE (64 << 10) /* 64k */ #define MAXRECSIZE (64 << 10) /* 64k */
#define check(val) if ((error = (val)) != 0) break #define check(val) if ((error = (val)) != 0) break
static int dflag; /* do not create a hint file, only write on stdout */ static bool dflag; /* do not create a hint file, only write on stdout */
static int verbose; static int verbose;
static FILE *fxref; /* current hints file */ static FILE *fxref; /* current hints file */
@ -76,12 +78,14 @@ static int reccnt; /* total record written to this file so far */
static void static void
intalign(void) intalign(void)
{ {
recpos = roundup2(recpos, sizeof(int)); recpos = roundup2(recpos, sizeof(int));
} }
static void static void
record_start(void) record_start(void)
{ {
recpos = 0; recpos = 0;
memset(recbuf, 0, MAXRECSIZE); memset(recbuf, 0, MAXRECSIZE);
} }
@ -89,22 +93,24 @@ record_start(void)
static int static int
record_end(void) record_end(void)
{ {
if (recpos == 0) if (recpos == 0)
return 0; return (0);
reccnt++; reccnt++;
intalign(); intalign();
fwrite(&recpos, sizeof(recpos), 1, fxref); fwrite(&recpos, sizeof(recpos), 1, fxref);
return fwrite(recbuf, recpos, 1, fxref) != 1 ? errno : 0; return (fwrite(recbuf, recpos, 1, fxref) != 1 ? errno : 0);
} }
static int static int
record_buf(const void *buf, int size) record_buf(const void *buf, size_t size)
{ {
if (MAXRECSIZE - recpos < size) if (MAXRECSIZE - recpos < size)
errx(1, "record buffer overflow"); errx(1, "record buffer overflow");
memcpy(recbuf + recpos, buf, size); memcpy(recbuf + recpos, buf, size);
recpos += size; recpos += size;
return 0; return (0);
} }
/* /*
@ -113,8 +119,9 @@ record_buf(const void *buf, int size)
static int static int
record_int(int val) record_int(int val)
{ {
intalign(); intalign();
return record_buf(&val, sizeof(val)); return (record_buf(&val, sizeof(val)));
} }
/* /*
@ -123,18 +130,19 @@ record_int(int val)
static int static int
record_string(const char *str) record_string(const char *str)
{ {
int len, error; int error;
size_t len;
u_char val; u_char val;
if (dflag) if (dflag)
return 0; return (0);
val = len = strlen(str); val = len = strlen(str);
if (len > 255) if (len > 255)
errx(1, "string %s too long", str); errx(1, "string %s too long", str);
error = record_buf(&val, sizeof(val)); error = record_buf(&val, sizeof(val));
if (error) if (error != 0)
return error; return (error);
return record_buf(str, len); return (record_buf(str, len));
} }
/* From sys/isa/pnp.c */ /* From sys/isa/pnp.c */
@ -155,7 +163,7 @@ pnp_eisaformat(uint32_t id)
idbuf[5] = hextoascii[(data[3] >> 4)]; idbuf[5] = hextoascii[(data[3] >> 4)];
idbuf[6] = hextoascii[(data[3] & 0xf)]; idbuf[6] = hextoascii[(data[3] & 0xf)];
idbuf[7] = 0; idbuf[7] = 0;
return(idbuf); return (idbuf);
} }
struct pnp_elt struct pnp_elt
@ -223,13 +231,15 @@ typedef TAILQ_HEAD(pnp_head, pnp_elt) pnp_list;
static int static int
parse_pnp_list(const char *desc, char **new_desc, pnp_list *list) parse_pnp_list(const char *desc, char **new_desc, pnp_list *list)
{ {
const char *walker = desc, *ep = desc + strlen(desc); const char *walker, *ep;
const char *colon, *semi; const char *colon, *semi;
struct pnp_elt *elt; struct pnp_elt *elt;
char *nd; char *nd;
char type[8], key[32]; char type[8], key[32];
int off; int off;
walker = desc;
ep = desc + strlen(desc);
off = 0; off = 0;
nd = *new_desc = malloc(strlen(desc) + 1); nd = *new_desc = malloc(strlen(desc) + 1);
if (verbose > 1) if (verbose > 1)
@ -243,7 +253,7 @@ parse_pnp_list(const char *desc, char **new_desc, pnp_list *list)
goto err; goto err;
strncpy(type, walker, colon - walker); strncpy(type, walker, colon - walker);
type[colon - walker] = '\0'; type[colon - walker] = '\0';
if (semi) { if (semi != NULL) {
if (semi - colon >= sizeof(key)) if (semi - colon >= sizeof(key))
goto err; goto err;
strncpy(key, colon + 1, semi - colon - 1); strncpy(key, colon + 1, semi - colon - 1);
@ -358,7 +368,7 @@ parse_pnp_list(const char *desc, char **new_desc, pnp_list *list)
} }
} }
*nd++ = '\0'; *nd++ = '\0';
return 0; return (0);
err: err:
errx(1, "Parse error of description string %s", desc); errx(1, "Parse error of description string %s", desc);
} }
@ -371,11 +381,14 @@ parse_entry(struct mod_metadata *md, const char *cval,
struct mod_version mdv; struct mod_version mdv;
struct mod_pnp_match_info pnp; struct mod_pnp_match_info pnp;
char descr[1024]; char descr[1024];
Elf_Off data = (Elf_Off)md->md_data; Elf_Off data;
int error = 0, i, len; int error, i;
size_t len;
char *walker; char *walker;
void *table; void *table;
data = (Elf_Off)md->md_data;
error = 0;
record_start(); record_start();
switch (md->md_type) { switch (md->md_type) {
case MDT_DEPEND: case MDT_DEPEND:
@ -524,7 +537,7 @@ parse_entry(struct mod_metadata *md, const char *cval,
} }
if (!error) if (!error)
record_end(); record_end();
return error; return (error);
} }
static int static int
@ -533,33 +546,25 @@ read_kld(char *filename, char *kldname)
struct mod_metadata md; struct mod_metadata md;
struct elf_file ef; struct elf_file ef;
void **p, **orgp; void **p, **orgp;
int error, eftype, nmlen; int error, eftype;
long start, finish, entries; long start, finish, entries;
char kldmodname[MAXMODNAME + 1], cval[MAXMODNAME + 1], *cp; char cval[MAXMODNAME + 1];
if (verbose || dflag) if (verbose || dflag)
printf("%s\n", filename); printf("%s\n", filename);
error = ef_open(filename, &ef, verbose); error = ef_open(filename, &ef, verbose);
if (error) { if (error != 0) {
error = ef_obj_open(filename, &ef, verbose); error = ef_obj_open(filename, &ef, verbose);
if (error) { if (error != 0) {
if (verbose) if (verbose)
warnc(error, "elf_open(%s)", filename); warnc(error, "elf_open(%s)", filename);
return error; return (error);
} }
} }
eftype = EF_GET_TYPE(&ef); eftype = EF_GET_TYPE(&ef);
if (eftype != EFT_KLD && eftype != EFT_KERNEL) { if (eftype != EFT_KLD && eftype != EFT_KERNEL) {
EF_CLOSE(&ef); EF_CLOSE(&ef);
return 0; return (0);
}
if (!dflag) {
cp = strrchr(kldname, '.');
nmlen = (cp != NULL) ? cp - kldname : (int)strlen(kldname);
if (nmlen > MAXMODNAME)
nmlen = MAXMODNAME;
strlcpy(kldmodname, kldname, nmlen);
/* fprintf(fxref, "%s:%s:%d\n", kldmodname, kldname, 0);*/
} }
do { do {
check(EF_LOOKUP_SET(&ef, MDT_SETNAME, &start, &finish, check(EF_LOOKUP_SET(&ef, MDT_SETNAME, &start, &finish,
@ -575,12 +580,12 @@ read_kld(char *filename, char *kldname)
sizeof(cval), cval)); sizeof(cval), cval));
parse_entry(&md, cval, &ef, kldname); parse_entry(&md, cval, &ef, kldname);
} }
if (error) if (error != 0)
warnc(error, "error while reading %s", filename); warnc(error, "error while reading %s", filename);
free(orgp); free(orgp);
} while(0); } while(0);
EF_CLOSE(&ef); EF_CLOSE(&ef);
return error; return (error);
} }
/* /*
@ -598,14 +603,14 @@ maketempfile(char *dest, const char *root)
if (snprintf(dest, MAXPATHLEN, "%.*slhint.XXXXXX", n, root) >= if (snprintf(dest, MAXPATHLEN, "%.*slhint.XXXXXX", n, root) >=
MAXPATHLEN) { MAXPATHLEN) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
return NULL; return (NULL);
} }
fd = mkstemp(dest); fd = mkstemp(dest);
if (fd < 0) if (fd < 0)
return NULL; return (NULL);
fchmod(fd, 0644); /* nothing secret in the file */ fchmod(fd, 0644); /* nothing secret in the file */
return fdopen(fd, "w+"); return (fdopen(fd, "w+"));
} }
static char xrefname[MAXPATHLEN], tempname[MAXPATHLEN]; static char xrefname[MAXPATHLEN], tempname[MAXPATHLEN];
@ -623,11 +628,12 @@ usage(void)
static int static int
compare(const FTSENT *const *a, const FTSENT *const *b) compare(const FTSENT *const *a, const FTSENT *const *b)
{ {
if ((*a)->fts_info == FTS_D && (*b)->fts_info != FTS_D) if ((*a)->fts_info == FTS_D && (*b)->fts_info != FTS_D)
return 1; return (1);
if ((*a)->fts_info != FTS_D && (*b)->fts_info == FTS_D) if ((*a)->fts_info != FTS_D && (*b)->fts_info == FTS_D)
return -1; return (-1);
return strcmp((*a)->fts_name, (*b)->fts_name); return (strcmp((*a)->fts_name, (*b)->fts_name));
} }
int int
@ -643,7 +649,7 @@ main(int argc, char *argv[])
while ((opt = getopt(argc, argv, "Rdf:v")) != -1) { while ((opt = getopt(argc, argv, "Rdf:v")) != -1) {
switch (opt) { switch (opt) {
case 'd': /* no hint file, only print on stdout */ case 'd': /* no hint file, only print on stdout */
dflag = 1; dflag = true;
break; break;
case 'f': /* use this name instead of linker.hints */ case 'f': /* use this name instead of linker.hints */
xref_file = optarg; xref_file = optarg;
@ -681,7 +687,7 @@ main(int argc, char *argv[])
/* close and rename the current hint file */ /* close and rename the current hint file */
fclose(fxref); fclose(fxref);
fxref = NULL; fxref = NULL;
if (reccnt) { if (reccnt != 0) {
rename(tempname, xrefname); rename(tempname, xrefname);
} else { } else {
/* didn't find any entry, ignore this file */ /* didn't find any entry, ignore this file */
@ -714,5 +720,5 @@ main(int argc, char *argv[])
read_kld(p->fts_path, p->fts_name); read_kld(p->fts_path, p->fts_name);
} }
fts_close(ftsp); fts_close(ftsp);
return 0; return (0);
} }