https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64703

            Bug ID: 64703
           Summary: glibc sysdeps/powerpc/powerpc64/dl-machine.h
                    miscompile
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: amodra at gmail dot com

This testcase, extracted from glibc sysdeps/powerpc/powerpc64/dl-machine.h
shows gcc optimising away the "opd" initialisation at -O1.  ie. it's as if the
indirect call doesn't cause gcc to see that "value" is used.  Adding the asm
cures the problem, as does passing the function pointer to another function
rather than calling via function pointer in resolve_ifunc.

struct link_map {
  unsigned long l_addr;
  int l_relocated;
};

typedef struct {
  unsigned long fd_func;
  unsigned long fd_toc;
  unsigned long fd_aux;
} Elf64_FuncDesc;

extern const struct link_map *dl_rtld_map;
extern unsigned long dl_hwcap;

unsigned long
resolve_ifunc (unsigned long value,
           const struct link_map *map, const struct link_map *sym_map)
{
  Elf64_FuncDesc opd;

  if (map != sym_map
      && sym_map != dl_rtld_map
      && !sym_map->l_relocated)
    {
      Elf64_FuncDesc *func = (Elf64_FuncDesc *) value;
      opd.fd_func = func->fd_func + sym_map->l_addr;
      opd.fd_toc = func->fd_toc + sym_map->l_addr;
      opd.fd_aux = func->fd_aux;
      value = (unsigned long) &opd;
    }
#if 0
  __asm__ ("#%0" : : "r" (value));
#endif
  return ((unsigned long (*) (unsigned long)) value) (dl_hwcap);
}

Reply via email to