aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.target/sh/torture/pr65505.c
blob: 3e930027094a366a9dafb247263eb2427f04f49c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* { dg-do compile }  */
/* { dg-additional-options "-std=gnu99" }  */
/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } }  */

struct thread_info {
 struct task_struct *task;
};

static inline __attribute__((always_inline))
              __attribute__((no_instrument_function))
struct thread_info *current_thread_info(void)
{
 struct thread_info *ti;

 unsigned long __dummy;

 __asm__ __volatile__ (
  "mov	r15, %0\n\t"
  "and	%1, %0\n\t"
  : "=&r" (ti), "=r" (__dummy)
  : "1" (~((1 << 13) - 1))
  : "memory");

 return ti;
}

typedef struct seqcount {
 unsigned sequence;
} seqcount_t;

struct inode;

struct dentry {
 seqcount_t d_seq;
 struct inode *d_inode;
};

struct path {
 struct vfsmount *mnt;
 struct dentry *dentry;
};

struct file {
 struct path f_path;
} __attribute__((aligned(4)));

struct task_struct
{
 int link_count, total_link_count;
 struct fs_struct *fs;
};

struct fd {
 struct file *file;
 unsigned int flags;
};

static inline __attribute__((always_inline))
              __attribute__((no_instrument_function))
struct fd
fdget_raw(unsigned int fd)
{
  return (struct fd){(struct file *)(fd & ~3),fd & 3};
}


struct fs_struct;

struct nameidata {
 struct path path;
 struct path root;
 struct inode *inode;
 unsigned int flags;
 unsigned seq, m_seq;
 struct file *base;
};

int read_seqcount_retry(const seqcount_t *s, unsigned start);

int
path_init(int dfd, const char *name, unsigned int flags,
          struct nameidata *nd)
{
 int retval = 0;

 if (*name=='/') {
  nd->path = nd->root;
 } else if (dfd == -100) {

  if (flags & 0x0040) {
   struct fs_struct *fs = (current_thread_info()->task)->fs;
  }
 } else {

  struct fd f = fdget_raw(dfd);
  struct dentry *dentry;

  if (!f.file)
   return -9;

  dentry = f.file->f_path.dentry;

  nd->path = f.file->f_path;
  if (flags & 0x0040) {
   if (f.flags & 1)
    nd->base = f.file;
  }
 }

 nd->inode = nd->path.dentry->d_inode;
 if (!(flags & 0x0040))
  goto done;
 if (__builtin_expect(!!(!read_seqcount_retry(&nd->path.dentry->d_seq, nd->seq)), 1))
  goto done;
 if (!(nd->flags & 0x2000))
  nd->root.mnt = ((void *)0);

 return -10;
done:
 (current_thread_info()->task)->total_link_count = 0;
 return 0;
}