[Prev][Next][Index][Thread]

Re: Overriding stuff from OSKit libs, some random remarks, and patches



>> Well, here's an idea:  perhaps all OSKit symbols should be declared
>> "weak" using __attribute__((weak));  From `info gcc`:
[snip]
>> As the OSKit's goal is to povide only the things you need, and to let
>> you do others, I think making all OSKit symbols weak would make sense.
>
>Good idea!
>
>> This does require, though, that all of the OSKit headers are modified.
>> It's a pity that the OSKit doesn't use a prototyping macro like GNU's,
>> because then all of the symbol declarations could be changed using
>> one #define.
>
>Maybe it would be quicker to enhance the linker with a new flag that
>says, ``the following objects/libraries only define weak symbols'' --
>but I'm not going to do that work. ;)

Well, this is not quite as good, but give it a try:  I just made a five-minute
hack to convert all global symbols in an ELF object file to be weak.  Here
it is:

----------------
/*
 * weaken.c: convert all symbols in an ELF file to be weak
 *
 * (C) 1999 Ramon van Handel <vhandel@chem.vu.nl>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include <elf.h>

int main(int argc, char *argv[])
/*
 * Convert all symbols in an ELF file to be weak
 *
 * INPUT:
 *     Command line stuff
 *
 * RETURNS:
 *     -1 on error, otherwise 0.
 */
{
    int ablfile;            /* The ELF file descriptor        */
    Elf32_Ehdr ablhdr;      /* The ELF header                 */
    Elf32_Shdr *shdrtbl;    /* The ELF section header table   */
    Elf32_Sym  *symtab;     /* The symbol table               */
    char       *strtab;     /* The ELF string table           */
    int i,j;

    /* Check whether we have enough parameters */
    if(argc<2) {
        printf("Usage:  weaken path/to/elffile\n");
        exit(-1);
    }

    /* Open the ELF file */
    if((ablfile = open(argv[1], O_RDWR)) == -1) {
        printf("Could not open ELF file %s\n", argv[1]);
        exit(-1);
    }

    /* Read the ELF header */
    if((read(ablfile,&ablhdr,sizeof(ablhdr)) < sizeof(ablhdr)) ||
       (ablhdr.e_ident[EI_MAG0] != ELFMAG0)                    ||
       (ablhdr.e_ident[EI_MAG1] != ELFMAG1)                    ||
       (ablhdr.e_ident[EI_MAG2] != ELFMAG2)                    ||
       (ablhdr.e_ident[EI_MAG3] != ELFMAG3)) {
        printf("%s not a correct ELF file\n", argv[1]);
        exit(-1);
    }

    if(!ablhdr.e_shoff) {
        printf("%s not a valid ELF file\n", argv[1]);
        exit(-1);
    }

    /* Move file offset to the section header table */
    lseek(ablfile,ablhdr.e_shoff,SEEK_SET);

    /* Load the section header table */
    shdrtbl = malloc(ablhdr.e_shnum*ablhdr.e_shentsize);
    for(i = 0; i < ablhdr.e_shnum; i++)
        read(ablfile,&shdrtbl[i],ablhdr.e_shentsize);

    /* Loop through the section header table and look for symbol tables */
    for(i = 0; i < ablhdr.e_shnum; i++) {
        if(shdrtbl[i].sh_type != SHT_SYMTAB && shdrtbl[i].sh_type != SHT_DYNSYM)
            continue;

        /* Load the symbol table */
        symtab = malloc(shdrtbl[i].sh_size);
        lseek(ablfile,shdrtbl[i].sh_offset,SEEK_SET);
        read(ablfile,symtab,shdrtbl[i].sh_size);

        /* Load the string table */
        strtab = malloc(shdrtbl[shdrtbl[i].sh_link].sh_size);
        lseek(ablfile,(shdrtbl[shdrtbl[i].sh_link].sh_offset),SEEK_SET);
        read(ablfile,strtab,shdrtbl[shdrtbl[i].sh_link].sh_size);

        /* Loop though the symbol table to find our symbols */
        for(j = 0; j < shdrtbl[i].sh_size / shdrtbl[i].sh_entsize; j++) {
		printf("Symbol \"%s\"\t\t", strtab+symtab[j].st_name);
		switch(ELF32_ST_BIND(symtab[j].st_info)) {
			case STB_GLOBAL:
				/* convert to weak */
				symtab[j].st_info &= 0xf;
				symtab[j].st_info |= (STB_WEAK << 4);

				lseek(ablfile,shdrtbl[i].sh_offset+(char *)&symtab[j].st_info-(char
*)symtab,SEEK_SET);
				write(ablfile,&symtab[j].st_info,sizeof(symtab[j].st_info));
				printf("was: global\tnow: weak\n");
				break;

			case STB_LOCAL:
				printf("was: local\tnow: local\n");
				break;

			case STB_WEAK:
				printf("was: weak\tnow: weak\n");
				break;

			default:
				printf("error in ELF file, probably corrupt\n");
		}
        }

        free(strtab);
        free(symtab);
    }

    /* Cleanup */
    close(ablfile);
    free(shdrtbl);

    /* We're done !!! */
    exit(0);
}
----------------

It *does* actually convert the symbols, I tested that.  However, I didn't
try to link the resulting library, just to objdump it, so I don't know
whether it works like you want it to.  But give it a try :)

>> > A few other minor problems I stumbled over:
>> >
>> > When building the OSKit by doing a "make" in the top-level directory,
>> > the make process sometimes aborts with a terse message similar to
>> > "make: Aborted".  Just restarting "make" finishes the build process.
>> > Any idea what's causing this?
>>
>> Do you also get signal 11's from GCC ?
>
>I'm not sure what the "Aborted" message means exactly... there is no
>message saying a signal is the reason for the abort, and the problem
>occurs rare enough to make trying to reproduce it a pain.

I had a similar problem once, turned out to be a bad SIMM.  My problems
were rare as well, but they didn't only occur in make.

Ramon



Follow-Ups: