[PATCH] include/obstack.h: do not hide _obstack_newchunk

Anthony G. Basile basile at opensource.dyc.edu
Mon Jun 24 13:25:20 UTC 2013


On 06/23/2013 05:25 PM, Anthony G. Basile wrote:
> On 06/23/2013 02:16 PM, Bernhard Reutner-Fischer wrote:
>> On 23 June 2013 18:14:08 "Anthony G. Basile" <basile at opensource.dyc.edu>
>> wrote:
>>> From: "Anthony G. Basile" <blueness at gentoo.org>
>>>
>>> Programs using obstacks, like the suite of utilities provided by
>>> coreutils, need _obstack_newchunk so we unhide the symbol.
>>
>> Eh, that sounds pretty broken. Are you sure this is the right thing to
>> do? They should most likely obstack_*grow() instead.
>>
>> Please fix coreutils instead, or better yet, use Busybox.
>> Thanks,
>

>
> Let me do some poking around and see what's going on.
>
>

Hi Bernhard,

Actually its pretty clear what's going on here.  Many obstack functions 
are implemented as macros around _obstack_newchunk, so "functions" like 
obstack_*grow() are decls which expand to calls to _obstack_newchunk. 
Read <obstack.h> around line 292.  Here's a simple poc:

#include <stdlib.h>
#include <obstack.h>
#include <malloc.h>
#include <string.h>

#define obstack_chunk_alloc malloc
#define obstack_chunk_free free

int
main()
{
	char *s;
	struct obstack myobs;

	obstack_init (&myobs);
	s = (char *)obstack_alloc (&myobs, 4); //here
	obstack_free (&myobs, NULL);

	exit(EXIT_SUCCESS);
}

Running cpp on it shows the line marked //here expands to:

  s = (char *)__extension__ ({ struct obstack *__h = (&myobs); 
__extension__ ({ struct obstack *__o = (__h); int __len = ((4)); if 
(__o->chunk_limit - __o->next_free < __len) _obstack_newchunk (__o, 
__len); ((__o)->next_free += (__len)); (void) 0; }); __extension__ ({ 
struct obstack *__o1 = (__h); void *__value = (void *) 
__o1->object_base; if (__o1->next_free == __value) 
__o1->maybe_empty_object = 1; __o1->next_free = ((sizeof (long int) < 
sizeof (void *) ? (__o1->object_base) : (char *) 0) + 
(((__o1->next_free) - (sizeof (long int) < sizeof (void *) ? 
(__o1->object_base) : (char *) 0) + (__o1->alignment_mask)) & 
~(__o1->alignment_mask))); if (__o1->next_free - (char *)__o1->chunk > 
__o1->chunk_limit - (char *)__o1->chunk) __o1->next_free = 
__o1->chunk_limit; __o1->object_base = __o1->next_free; __value; }); });

and readelf -s on the obj show the following UND as expected:

UND _GLOBAL_OFFSET_TABLE_
UND malloc
UND free
UND _obstack_begin
UND _obstack_newchunk
UND obstack_free
UND exit



-- 
Anthony G. Basile, Ph. D.
Chair of Information Technology
D'Youville College
Buffalo, NY 14201
(716) 829-8197


More information about the uClibc mailing list